#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

#include <bits/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/types.h>

#include <netdb.h>
#include <arpa/inet.h>


#include "udpServer.h"
#include "cJSON.h"
#include <sys/select.h>
#include <time.h>
#include <bits/types/struct_timeval.h>

static int port = 0;
static int ip = 0;

static unsigned char udpBuff[1400] = { 0 };

int ParseRecvJsonData(const char * recvdata, int *outLogLevel)
{
    int nRet = -1;
    *outLogLevel = -1;

    if(NULL == recvdata)
    {
        return -1;
    }

    cJSON *parseRoot = NULL;
    cJSON *levelItem = NULL;
 
    parseRoot = cJSON_Parse(recvdata);

    if (parseRoot)
    {
        levelItem = cJSON_GetObjectItem(parseRoot, "level");
        if (levelItem)
        {
            *outLogLevel =  levelItem->valueint;
            nRet = 0;
        }
        else
        {
            nRet = -1;
            goto end;
        }
 
    }
    else
    {
        nRet = -1;
        goto end;
    }
 
    end: 
        if (parseRoot)
        {
            cJSON_Delete(parseRoot);    
            parseRoot = NULL;
        }
        return nRet;
}

int WriteLogLevelToFileJson(const char *filePathName, int logLevel)
{
    int nRet = 0;
    cJSON * rootWriteFile = NULL;

    if((NULL == filePathName) || (logLevel < 1) ||
      (logLevel > 8))
    {
        return -1;
    }

    rootWriteFile = cJSON_CreateObject(); 
    if (rootWriteFile)
    {
        cJSON_AddNumberToObject(rootWriteFile,"level",logLevel);    
        char *fileStream = cJSON_Print(rootWriteFile);   //convert json to buf

        FILE *fid;
        fid = fopen(filePathName,"w");
        if (!fid)
        {
            printf("open file faild \n");
            nRet = -1;
        }

        nRet = fwrite(fileStream, sizeof(char), strlen(fileStream), fid);
        if (!nRet)
        {
            printf("写出文件出错\n");
            nRet = -1;
        }
 
        nRet = fclose(fid);
        if (nRet)
        {
            printf("close fileFd faild \n");    
            nRet = -1;
        }   
    }
    else
    {
        nRet = -1;
    }
 
    if (rootWriteFile)
    {
        cJSON_Delete(rootWriteFile);
        rootWriteFile = NULL;
    }  
 
    return nRet;
}

int SocketServerInit(const char *ip, int port)
{
    int nRet = -1;
    int sockfd = -1;
    struct sockaddr_in server_addr;

    if((NULL == ip) || (port < 0) || (port > 65535))
    {
        return -1;
    }

    sockfd = socket(AF_INET, SOCK_DGRAM, 0);
    if (sockfd < 0)
    {
        printf("create socket faild \n");
        return -1;
    }

    bzero(&server_addr, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(ip);
    server_addr.sin_port = htons(port);

    nRet = bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    if (nRet < 0) {
        printf("bind socket faild \n");
        close(sockfd);
        return -1;
    }
}

int RecDataFromClient(int serverFd)
{
    struct timeval timeout;
	timeout.tv_sec = 0;
	timeout.tv_usec = 500000; //500ms

	fd_set fsRead;
    int iReceived = 0;
    while(1)
    {
        FD_ZERO( &fsRead );
		FD_SET(serverFd, &fsRead);
		int ret = select (1024, &fsRead, NULL, NULL, &timeout);
        if (ret < 0)
		{
		}
		else if (ret == 0)
		{
			//OnTimer();
		}
		else 
		{
            if(FD_ISSET( serverFd, &fsRead)) {
                struct sockaddr_in sockAddr;
                bzero(&sockAddr,sizeof(struct sockaddr_in));
                int nSockAddrLen = sizeof(sockAddr);
                int iReceived = recvfrom(serverFd, udpBuff, sizeof(udpBuff), 0, (struct sockaddr*)&sockAddr, (socklen_t*)&nSockAddrLen);
                port= ntohs(sockAddr.sin_port);
                ip = sockAddr.sin_addr.s_addr;
            }
        }
        timeout.tv_sec = 0;
		timeout.tv_usec = 500000;	
    }
}

int udpServer()
{
    int socketServerFd = -1;
    socketServerFd = SocketServerInit("127.0.0.1", 9999);
    if(-1 == socketServerFd)
    {
        printf("create socket server fd faild \n");
    }

    RecDataFromClient(socketServerFd);

    return 0;
}
